home *** CD-ROM | disk | FTP | other *** search
- ACMDs
-
- Code resources of type 'ACMD' allow the user to add
-
- modules of user-written code to Alpha. These modules
-
- typically implement functionality that is too complex
-
- for Alisp functions, or would be too slow. When an ACMD
-
- is loaded, it is passed a pointer to a chunk of file
-
- text (usually the selected text). The ACMD transforms
-
- the text and returns a pointer to the transformed text
-
- as a result. ACMDs can access Alpha flags and variables,
-
- as well as define variables that Alpha maintains between
-
- ACMD invocations. Example ACMDs included in this
-
- distribution wrap text, insert the current data, and
-
- play sounds.
-
-
- The following is the way the 'main' routine of your ACMD
-
- should be declared:
-
-
- /* pointer to a function that returns an 'int' */
-
- typedef int (*FPtr)();
-
-
- char *main(text, alert, getVar, setVar, defVar,
-
- delVar)
-
- char *text;
-
- FPtr alert, getVar, setVar, defVar, delVar;
-
- {
-
- : : :
-
- return (text);
-
- }
-
-
- 'text' points to a null-terminated block of text
-
- allocated with 'NewPtr'. Your routine must return a
-
- similarly allocated block of text as its result. If the
-
- two are not the same block, you are responsible for
-
- deallocating the input block. Alpha will deallocate the
-
- block of text returned by the ACMD. The exception is
-
- when the ACMD returns NULL. In this case no deallocation
-
- is performed. 'text' is usually a copy of the currently
-
- selected text. However, macros can call ACMDs with other
-
- selections.
-
-
- Callback Functions
-
-
- Each of the last five arguments is a pointer to a
-
- callback function, an Alpha function that allows your
-
- ACMD to interact with Alpha's internal variables or
-
- display information.
-
-
- The 'alert' parameter is a pointer to a function that
-
- accepts the same arguments as the C 'printf' command,
-
- displaying the result in an alert box. Bear in mind
-
- that Alpha is compiled with 16-bit integers, so if you
-
- are calling Alert from a code resource that was compiled
-
- with 32-bit ints, you must print your integers with
-
- '%ld' instead of '%d'.
-
-
- Each of the last four parameters is a pointer to an
-
- Alpha function that your ACMD can call to read or modify
-
- Alpha variables. Internally, Alpha prototypes these
-
- functions as:
-
-
- /***********************************************
-
- * *
-
- * Return the longword value of the variable *
-
- * named by 'name' in 'val'. Works for either *
-
- * Alpha predefined vars or those defined with *
-
- * 'defineVar' below. Returns zero if the var *
-
- * doesn't exist. *
-
- * *
-
- ***********************************************/
-
- int getVar(char *name, long *val);
-
-
-
- /***********************************************
-
- * *
-
- * Return the longword value of the variable *
-
- * named by 'name'. Works for either Alpha *
-
- * predefined vars or those defined with *
-
- * 'defineVar' below. Returns 0 if the var *
-
- * doesn't exist. To be sure that Think passes *
-
- * a longword value for 'val', always typecast *
-
- * 'val' to a long when you call this routine. *
-
- * *
-
- ***********************************************/
-
- int setVar(char *name, long val);
-
-
-
- /************************************************
-
- * *
-
- * Define a longword variable named 'name' with *
-
- * Initial value 'val'. *
-
- * Return 0 if the var already exists. *
-
- * *
-
- ************************************************/
-
- int defineVar(char *name, long val)
-
-
-
- /*******************************************
-
- * *
-
- * Define a longword variable named 'name'. *
-
- * Return 0 if the variable doesn't exist. *
-
- * *
-
- *******************************************/
-
- int deleteVar(char *name);
-
-
-
- These functions allow your ACMDs to behave differently
-
- according to the current state of Alpha and the text you
-
- are viewing. ACMDs can pass data among themselves by
-
- defining their own variables. ACMD-defined variables can
-
- also hold pointer values, allowing ACMDs to have
-
- persistent storage. Note that while user variables and
-
- Alpha string variables are long words, ordinary Alpha
-
- variables such as 'indentOnCR' and 'regExpr' are shorts.
-
- So even while you MUST pass in a longword value to set
-
- an Alpha internal variable, only 16 bits are actually
-
- used internally.
-
-
- In summary, when an ACMD is called:
-
-
- • The selected code resource is loaded into memory
-
- and locked.
-
-
- • A new pointer is allocated with size equal to the
-
- size of the current selection + 1.
-
-
- • The selection (if any) is copied into the new
-
- pointer. The string will be null-terminated w/
-
- carriage returns to delimit lines.
-
-
- • The 'ACMD' resource is called as a 'C' function w/
-
- the text pointer and the function pointers as it's
-
- parameters.
-
-
- • The ACMD transforms the string, and returns it or
-
- NULL as it's result.
-
-
- • The original selection is replaced with the
-
- transformed text.
-
-
- • The ACMD resource is released.
-
-
- Code resources of type 'ACMD' in Alpha's resource fork
-
- are added to the ACMD menu under 'Utilities' and are
-
- callable from macros (macros allow ACMD functions to be
-
- bound to keystrokes). ACMDs can be added to Alpha's
-
- resource fork by using ResEdit.
-
-
- Since ACMDs are code resources, they must reference
-
- their data off of register A4 instead of the usual A5.
-
- From the standpoint of a C compiler like Think C, all
-
- this means is that your main file must include the
-
- header "SetUpA4.h", your program should begin with calls
-
- to "RememberA0()" and "SetUpA4()", and it should end
-
- with "RestoreA4()". MPW has similar setup routines. Note
-
- that these routines use self-modifying code to store the
-
- value of A4 on entry. Self-modifying code will not work
-
- under A/UX, and probably not under system 8.0, whatever
-
- decade that comes out. IM 6 has a workaround, for those
-
- interested.
-
-
- If the ACMD needs to link in library routines, care must
-
- be taken to ensure that the libraries don't have any
-
- global data references off of register A5. MacTraps of
-
- ThinkC is fine. The ANSI library does declare globals,
-
- but there is a version of the ANSI library that uses A4
-
- instead of A5. Linking your code with MacTraps and
-
- ANSI-A4 should take care of most of your library needs.
-
-
-